#include "rectMeshFunctions.hpp"
#include "uniMesh.hpp"
#include "rectMesh.hpp"

namespace hms
{

/**
 * @brief Returns a Replicate expr of a normal vector for either horizontal
 * or vertical edges. 
 * 
 * @tparam orien: Orientation of the edge.
 * Can be EdgeRange::vertical or EdgeRange::horizontal.
 * @param nEdges Number of (continuous) edges of the specified orientation.
 * Is used as the number of replications.
 * 
 * @return Eigen::Replicate<const Vector2s, 1, Dynamic> 
 */
template<EdgeRange orien>
RectNormalRepl rectNormals( const Index& nEdges ){
	if constexpr ( orien == EdgeRange::horizontal ){
		static const Vector2s normalH {0, 1};
		return {normalH, 1, nEdges};
	} else if constexpr ( orien == EdgeRange::vertical ){
		static const Vector2s normalV {1, 0};
		return {normalV, 1, nEdges};
	}
}

template RectNormalRepl rectNormals<EdgeRange::horizontal>( const Index& );
template RectNormalRepl rectNormals<EdgeRange::vertical  >( const Index& );

auto rectNormals( const Array2i& meshSize, const Index& nEdges ) -> RectNormalsType
{
	// static const Vector2s normalH { 0, 1 }; // for horizontal edges
	// static const Vector2s normalV { 1, 0 }; // for vertical edges

	const Index
		nh { nHorizontalEdges( meshSize ) },
		nv { nEdges - nh };

	return concat_horizontal(
		rectNormals<EdgeRange::horizontal>(nh),
		rectNormals<EdgeRange::vertical  >(nv)
		// Eigen::Replicate<Vector2s, 1, Dynamic>{normalH, 1, nh},
		// Eigen::Replicate<Vector2s, 1, Dynamic>{normalV, 1, nv}
		// normalH.replicate(1, nh),
		// normalV.replicate(1, nv)
	);
}

auto rectEdgeNormal(EdgeRange range) -> Vector2s {
	if (range == EdgeRange::horizontal)
		return {0,1};
	else
		return {1,0};
}

} // namespace hms
